Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First steps to move to SQLDelight #47

Open
wants to merge 110 commits into
base: master
Choose a base branch
from
Open

First steps to move to SQLDelight #47

wants to merge 110 commits into from

Conversation

raphaelm
Copy link
Member

No description provided.

@raphaelm raphaelm changed the title Sqldelight First steps to move to SQLDelight Jul 19, 2024
packageName = "eu.pretix.libpretixsync.sqldelight"
srcDirs('src/main/sqldelight/sqlite', 'src/main/sqldelight/common', 'src/main/sqldelight/migrations')

version = 105
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm worried we'll forget to keep this in sync between build.gradle and build-postgres.gradle, can we move it to its own gradle file and import it from there?

Copy link
Collaborator

@antweb antweb Sep 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if this is needed at all, since the version it deducts from the migration is prioritized anyway? I'll check if we can just remove it. If not, I agree that it should go into a common file

for (i in 0 until checkins.length()) {
val ci = checkins.getJSONObject(i)
val listid = ci.getLong("list")
if (known.containsKey(listid)) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that it was the same in the old code, but reading this… this is wrong, isn't it? How did this ever work? We would need to use the server ID of the checkin here, not the list ID?

@robbi5 what do you think?

@antweb antweb force-pushed the sqldelight branch 3 times, most recently from d7ede36 to 04b5936 Compare July 25, 2024 15:39
@antweb antweb force-pushed the sqldelight branch 3 times, most recently from d835bc1 to 58026f1 Compare July 31, 2024 15:27
override fun getOptions(): List<QuestionOption>? = _options

override fun requiresAnswer(): Boolean = required

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation of getDependencyValues is missing! This breaks dependencies between questions.

Here's a good event for testing:
https://staging.pretix.eu/control/event/postest/questions/questions/

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in bd295fb.

Should we make getDependency() and getDependencyValues() abstract in QuestionLike? Or are there many cases that rely on the defaults?

}

override fun update(obj: BlockedTicketSecret, jsonobj: JSONObject) {
// TODO: Test new behaviour. Original version had no update case
Copy link
Member Author

@raphaelm raphaelm Sep 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a specialty about blocked secrets: We don't care about a BlockedTicketSecret with blocked=false. The only reason it exists on the API layer is to allow for differential sync during updates. But there is no need to store it. So instead of updating the blocked field to 0, we can and should just delete the local database entry.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correction, the old code does change the blocked field to false, but it never inserts a new row with blocked=false, and the new code does the same, so maybe this is correct this way.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also have the clean-up call (db.blockedTicketSecretQueries.deleteNotBlocked()) in download(). That should clean up any rows that have been updated to blocked=false.
The only thing I wonder is if we can simplify any of this to make it more maintainable (e.g. no special treatment in insert()/update() and just a clean-up in download() maybe?). The performance impact of inserting / updating a few rows too many shouldn't be too significant (?)

Comment on lines 143 to 146
if (autoPersist()) {
insert(jsonobj)
inserted += 1
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we do no batching any more, autoPersist() does not make much sense any more. In fact, with autoPersist returning false, as e.g. the case for BlockedTicketSecretSyncAdapter, no data is saved any more!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree. Now that the implementations of insert/update contain the DB queries, there is no need to distinguish on BaseDownloadSyncAdapter level. And with the current code it's very easy to make the mistake of defaulting to false like I did in the BlockedTicketSecretSyncAdapter

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@antweb antweb force-pushed the sqldelight branch 3 times, most recently from 41615cb to 8b87835 Compare November 1, 2024 17:41
@robbi5 robbi5 marked this pull request as ready for review November 7, 2024 15:28
import java.util.Date
import java.util.TimeZone

class AndroidUtilDateAdapter : ColumnAdapter<Date, String> {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this adapter be used by JVM as well or is it really android specific?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's specific to how requery saved Date values as strings to the DB on Android. While we get 2024-11-13T09:49:28Z there, it uses a different format on a plain JVM (2024-11-13 09:49:28.210).
In theory, you can use this adapter in other places. But you probably want the JavaUtilDateAdapter for backwards compatibility on the JVM.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We found a bug in there actually. You might want to check out a566d2d

It returns the result of apiCall, which is non-null.
Since we no longer inherit from classes like AbstractReceipt, the JSON
utils must be added separately.
Removes the positionid of the add-on parent from the JSON and replaces
it with just the addon_to ID.
With SQLDelight, we can no longer directly resolve the relation with
just the addon_to field, which means that we have to pass in either the
ReceiptLine that addon_to points to or its positionid.
Since the toJSON() is mostly used for logging purposes and the
positionid is not strictly required, we can simplify the function here
and add the equivalent of addon_to.positionid to the JSON afterwards in
the caller where required.
Provide the same functionality as the getters on AbstractItem, but for
the SQLDelight query result.
antweb and others added 27 commits November 22, 2024 15:32
Question models were missing the getDependencyValues() override.
We were providing the wrong type of Instant.
Some query building code remains which should be migrated in a separate
step.
SQLDelight returns the Long value directly on Postgres while it wraps it
in a result type on SQLDelight.
…droid is too old for TRUE/FALSE (PRETIXPOS-1HH)
Since SimpleDateFormat is not thread safe, we might be running into race
conditions here actually.
Re-creating a new instance is expensive, so this is only a temporary
fix while we validate a change to DateTimeFormatter.
Should guarantee thread safety without constantly re-creating formatters.
Reduces warnings when we convert them to models.
The change in cce5bf9 fixed booleans on older SQLite versions, but broke
the queries for Postgres. This is a workaround that should make both
databases happy.
Since Postgres is extra pedantic in CASE epxressions, the complex order
position queries had to be moved to the set of dialect-specific queries.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants